package com.ionehe.group.common.uaa.ex.config;

import com.ionehe.group.common.io.Response;
import com.ionehe.group.common.uaa.ex.domain.service.AdminReadService;
import com.ionehe.group.common.uaa.ex.domain.service.FunctionReadService;
import com.ionehe.group.common.uaa.ex.domain.service.UserReadService;
import com.ionehe.group.common.uaa.ex.dto.FunctionDTO;
import com.ionehe.group.common.uaa.ex.enums.ErrorMessages;
import com.ionehe.group.common.uaa.ex.exception.BusinessException;
import com.ionehe.group.common.user.c.sdk.uaa.config.SecurityConfig;
import com.ionehe.group.common.user.c.sdk.uaa.service.DynamicSecurityService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.List;
import java.util.Objects;
import java.util.Vector;

/**
 * Copyright (c) 2020 ionehe.com
 * Date: 2020/9/15
 * Time: 下午10:58
 *
 * @author 2020年 <a href="mailto:a@ionehe.com">秀</a>
 * security模块相关配置
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Slf4j
public class PermissionsSecurityConfig extends SecurityConfig {
    @Autowired
    private AdminReadService manageInfoReadService;
    @Autowired
    private FunctionReadService functionReadService;
    @Autowired
    private UserReadService userReadService;

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        //获取登录用户信息
        return username -> {
            // 开发者/平台管理员
            Response<UserDetails> isAdminRes = manageInfoReadService.loadUserByUsername(username);
            if (!isAdminRes.success()) throw new BusinessException(isAdminRes.getMessage());
            if (Objects.nonNull(isAdminRes.getData())) return isAdminRes.getData();

            // 非开发者/平台管理员
            Response<UserDetails> nonAdminRes = userReadService.loadUserByUsernameAndAccountType(username, null);
            if (!nonAdminRes.success()) throw new BusinessException(nonAdminRes.getMessage());
            if (Objects.nonNull(nonAdminRes.getData())) return nonAdminRes.getData();

            throw new UsernameNotFoundException(ErrorMessages.USER_ACCOUNT_OR_PASSWORD_ERROR.toString());
        };
    }

    @Bean("dynamicSecurityService")
    @DependsOn("uaaExDBInitializer")
    public DynamicSecurityService dynamicSecurityService() {

        return () -> {
            List<ConfigAttribute> list = new Vector<>();
            Response<List<FunctionDTO>> res = functionReadService.listAll();
            List<FunctionDTO> resourceList = res.getData();
            for (FunctionDTO resource : resourceList) {
                list.add(new org.springframework.security.access.SecurityConfig(resource.getUrl()));
            }
            log.debug("PermissionsSecurityConfig[]resource:{}", list);
            return list;
        };
    }
}
